package com.ctshk.rpc.order.goods.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.constant.ElasticSearchConstant;
import com.ctshk.common.constant.RedisConstants;
import com.ctshk.common.dto.Result;
import com.ctshk.common.elasticsearch.config.ElasticSearchConfiguration;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO;
import com.ctshk.rpc.order.goods.dto.*;
import com.ctshk.rpc.order.goods.dto.resp.CommodityCostAttributeResp;
import com.ctshk.rpc.order.goods.dto.resp.CommodityCostResp;
import com.ctshk.rpc.order.goods.dto.resp.CommodityInfoResp;
import com.ctshk.rpc.order.goods.entity.*;
import com.ctshk.rpc.order.goods.mapper.*;
import com.ctshk.rpc.order.goods.req.conmodity.*;
import com.ctshk.rpc.order.goods.service.ICommodityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品表 服务实现类
 * </p>
 *
 * @author 姜斌文
 * @since 2021-04-13
 */
@Slf4j
@DubboService
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Commodity> implements ICommodityService {

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private CommodityAttributeMapper commodityAttributeMapper;

    @Autowired
    private CommodityCostAttributeMapper costAttributeMapper; // 商品成本属性mapper

    @DubboReference
    private com.ctshk.rpc.goods.service.ICommodityService commodityService;

    @Autowired
    private CommodityKeyWordMapper keyWordMapper;

    @Autowired
    private CommodityLabelMapper labelMapper;

    @Autowired
    private CommodityRecommendMapper recommendMapper;

    @Autowired
    private CommodityFileMapper fileMapper;

    @Autowired
    private CommodityCostMapper costMapper;

    @Autowired
    private ShoppingCommoditySpecificationsNameMapper specificationsNameMapper; // 商城商品规格名称mapper

    @Autowired
    private ShoppingCommoditySpecificationsMapper specificationsMapper; // 商城商品规格mapper

    @Autowired
    private ShoppingCommoditySpecificationsAttributeMapper specificationsAttributeMapper; // 商城商品规格屬性mapper

    @Autowired
    private ElasticSearchCommodityMapper elasticSearchCommodityMapper;  // 商品分类es

    @Autowired
    private ShoppingSpecialCommodityMapper shoppingSpecialCommodityMapper;

    @Autowired
    private RestHighLevelClient restHighLevelClient; // es操作类

    @Autowired
    private ShoppingSpecialMapper shoppingSpecialMapper; // 商品专题Mapper

    @Autowired
    private RedisTemplate<String, Object> redisTemplate; // redis操作类

    @Override
    public Result<CommodityDTO> findCommodityById(Long id) {
        if (null == id) {
            throw new BusinessException(SystemError.SYS_402);
        }

        // 获取商品主表信息
        Commodity commodity = commodityMapper.selectCommodityById(String.valueOf(id));
        CommodityDTO commodityDTO = new CommodityDTO();
        if (commodity != null) {
            BeanUtils.copyProperties(commodity, commodityDTO);

            // 查询商品属性信息
            CommodityAttribute commodityAttribute = commodityAttributeMapper.findCommodityAttributeByCommodityId(commodity.getId());
            if (commodityAttribute != null) {
                CommodityAttributeReq commodityAttributeReq = new CommodityAttributeReq();
                BeanUtils.copyProperties(commodityAttribute, commodityAttributeReq);
                commodityDTO.setCommodityAttributeReq(commodityAttributeReq);
            }
        } else {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23033);
        }


        // 获取商品关键词信息
        List<CommodityKeyWord> dbCommodityKeyWordList = keyWordMapper.findCommodityKeyWordByCommodityId(commodityDTO.getId());
        List<CommodityKeyWordReq> commodityKeyWordReqList = new ArrayList<>();
        for (CommodityKeyWord dbKeyWord : dbCommodityKeyWordList) {
            CommodityKeyWordReq keyWordReq = new CommodityKeyWordReq();
            BeanUtils.copyProperties(dbKeyWord, keyWordReq);
            commodityKeyWordReqList.add(keyWordReq);

        }
        if (null != commodityKeyWordReqList && commodityKeyWordReqList.size() > 0) {
            commodityDTO.setCommodityKeyWordReqList(commodityKeyWordReqList);
        }

        // 获取商品标签信息
        List<CommodityLabel> dbCommodityLabelList = labelMapper.findCommodityLabelByCommodityId(commodityDTO.getId());
        List<CommodityLabelReq> commodityLabelReqList = new ArrayList<>();
        for (CommodityLabel dbLabel : dbCommodityLabelList) {
            CommodityLabelReq labelReq = new CommodityLabelReq();
            BeanUtils.copyProperties(dbLabel, labelReq);
            commodityLabelReqList.add(labelReq);

        }
        if (null != commodityLabelReqList && commodityLabelReqList.size() > 0) {
            commodityDTO.setCommodityLabelReqList(commodityLabelReqList);
        }

        // 获取商品推荐信息
        List<CommodityRecommend> dbCommodityRecommendList = recommendMapper.findCommodityRecommendByCommodityId(commodityDTO.getId());
        List<CommodityRecommendReq> commodityRecommendReqList = new ArrayList<>();
        for (CommodityRecommend dbRecommend : dbCommodityRecommendList) {
            CommodityRecommendReq recommendReq = new CommodityRecommendReq();
            BeanUtils.copyProperties(dbRecommend, recommendReq);
            commodityRecommendReqList.add(recommendReq);

        }
        if (null != commodityRecommendReqList && commodityRecommendReqList.size() > 0) {
            commodityDTO.setCommodityRecommendReqList(commodityRecommendReqList);
        }

        // 获取商品文件信息
        List<CommodityFile> dbCommodityFileList = fileMapper.findCommodityFileByCommodityId(commodityDTO.getId());
        List<CommodityFileReq> commodityFileReqList = new ArrayList<>();
        for (CommodityFile dbCommodityFile : dbCommodityFileList) {
            CommodityFileReq commodityFileReq = new CommodityFileReq();
            BeanUtils.copyProperties(dbCommodityFile, commodityFileReq);
            commodityFileReqList.add(commodityFileReq);
        }
        if (null != commodityFileReqList && commodityFileReqList.size() > 0) {
            commodityDTO.setCommodityFileReqList(commodityFileReqList);
        }

        // 获取商品属性信息
        CommodityAttributeReq attributeReq = commodityDTO.getCommodityAttributeReq();
        if (attributeReq.getSpecificationsType().intValue() == 1) { // 当类型为1：即为单规格类型
            com.ctshk.rpc.order.goods.req.conmodity.CommodityCostReq commodityCostReq = null;
            List<CommodityCost> dbCommodityCostList = costMapper.findCommodityCostByCombinedIds(commodityDTO.getId(), attributeReq.getId(), null);
            if (null != dbCommodityCostList && dbCommodityCostList.size() > 0) {
                CommodityCost dbCommodityCost = dbCommodityCostList.get(0);
                commodityCostReq = new CommodityCostReq();
                BeanUtils.copyProperties(dbCommodityCost, commodityCostReq);
            }
            if (null != commodityCostReq) {
                commodityDTO.setCommodityCostReq(commodityCostReq);
            }
        } else { // 当类型为2：即为多规格类型
            setMultiSpecificationRelatedParamInfo(commodityDTO, attributeReq);
        }
        return Result.success(commodityDTO);
    }

    @Override
    public List<CommodityDTO> selectCommodityDTOListByIds(List<Long> ids) {
        List<Commodity> commodities = commodityMapper.selectBatchIds(ids);
        return EntityUtil.copyList(commodities, CommodityDTO.class);
    }

    /**
     * 查询商品数据封装
     *
     * @param lastNow
     * @return
     */
    public List<com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO> findCommodityAllList(LocalDateTime lastNow) {
        // 过滤商品主表数据，根据主表数据去组装其他数据参数
        List<com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO> commodityList = commodityMapper.findCommodityInfoList(null);
        if (CollectionUtils.isEmpty(commodityList)) {
            return null;
        }
        Map<Long, List<CommodityLabelDTO>> labelMap = null;
        Map<Long, List<CommodityFileDTO>> fileMap = null;
        Map<Long, List<CommodityKeyWordDTO>> keyWordMap = null;
        Map<Long, List<CommodityRecommendDTO>> recommendMap = null;
        Map<Long, List<com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO>> singlesMap = null;

        List<Long> commodityIds = commodityList.stream().map(p -> p.getId()).collect(Collectors.toList());

        // 获取商品标签，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityLabelDTO> labelList = labelMapper.findHtmlFiveCommodityLabelByCommodityIds(commodityIds);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(labelList)) {
            labelMap = labelList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 获取商品文件，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityFileDTO> fileList = fileMapper.findHtmlFiveCommodityFileByCommodityIds(commodityIds);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(fileList)) {
            fileMap = fileList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 获取商品关键词，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityKeyWordDTO> keyWordList = keyWordMapper.findHtmlFiveCommodityKeyWordByCommodityIds(commodityIds);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(keyWordList)) {
            keyWordMap = keyWordList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 获取商品推荐，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityRecommendDTO> recommendList = recommendMapper.findHtmlFiveCommodityRecommendByCommodityIds(commodityIds);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(recommendList)) {
            recommendMap = recommendList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 商品其他属性 一对一 查询赋值
        for (com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO commodityAllList : commodityList) {
            Long commodityId = commodityAllList.getId();
            commodityAllList.setId(commodityId);
            commodityAllList.setCommodityLabels(null == labelMap ? null : labelMap.get(commodityId));
            commodityAllList.setCommodityFiles(null == fileMap ? null : fileMap.get(commodityId));
            commodityAllList.setCommodityKeyWords(null == keyWordMap ? null : keyWordMap.get(commodityId));
            commodityAllList.setCommodityRecommends(null == recommendMap ? null : recommendMap.get(commodityId));
        }

        // 区分 单/多规格类型数据，因为组装的参数涉及表关联关系不一样
        Map<Integer, List<com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO>> specificationsTypeMap = commodityList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityAttribute().getSpecificationsType()));
        List<com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO> singles = specificationsTypeMap.get(1);
        List<com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO> multiples = specificationsTypeMap.get(2);

        // 单规格参数组装
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(singles)) {
            Map<Long, List<CommodityCostDTO>> costs = getSingleCommodityCostMapByAttributeId(singles);
            for (com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO singlesCommodityAllList : singles) {
                Long commodityAttributeId = singlesCommodityAllList.getCommodityAttribute().getId();
                List<CommodityCostDTO> temps = costs.get(commodityAttributeId);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(temps)) {
                    singlesCommodityAllList.setCommodityCosts(temps);
                }
            }
//            singlesMap = singles.stream().collect(Collectors.groupingBy(obj -> obj.getId()));
            for (com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO commodityAllList : commodityList) {
                for (com.ctshk.rpc.order.goods.dto.CommodityInfoListDTO single : singles) {
                    if (commodityAllList.getId().longValue() == single.getId().longValue()) {
                        commodityAllList.setCommodityCosts(null == single ? null : single.getCommodityCosts());
                    }
                }
            }
        }

        // 多规格参数组装
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(multiples)) {
            Map<Long, List<CommodityCostAttributeDTO>> costAttributes = getMultipleCommodityCostAttributeMapByAttributeId(multiples);
            for (CommodityInfoListDTO multipleCommodityAllList : multiples) {
                Long commodityAttributeId = multipleCommodityAllList.getCommodityAttribute().getId();
                List<CommodityCostAttributeDTO> temps = costAttributes.get(commodityAttributeId);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(temps)) {
                    multipleCommodityAllList.setCommodityCostAttributes(temps); // 讲商品成本属性设置到对应的商品对象
                    // 获取商品成本属相对应的商品成本
                    List<Long> costAttributeIds = temps.stream().map(p -> p.getId()).collect(Collectors.toList());
                    List<CommodityCost> commodityCostList = costMapper.selectByCommodityIdAndAttrId(multipleCommodityAllList.getCommodityAttribute().getCommodityId(), commodityAttributeId, costAttributeIds, IsDeletedCode.NO.getCode());
                    List<CommodityCostDTO> resultCostList = EntityUtil.copyList(commodityCostList, CommodityCostDTO.class);
                    Map<Long, List<CommodityCostDTO>> costAttributeMap = resultCostList.stream().collect(Collectors.groupingBy(obj -> obj.getCostAttributeId()));

                    for (CommodityCostAttributeDTO costAttribute : multipleCommodityAllList.getCommodityCostAttributes()) {
                        Long costAttributeId = costAttribute.getId();
                        List<CommodityCostDTO> commodityCost = costAttributeMap.get(costAttributeId);
                        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(commodityCost)) {
                            costAttribute.setCommodityCost(commodityCost.get(0));
                        }
                    }
                }
            }
//            for (CommodityInfoListDTO commodityAllList : commodityList) {
//                for (CommodityInfoListDTO multiple : multiples) {
//                    if (commodityAllList.getId().longValue() == multiple.getId().longValue()) {
//                        commodityAllList.setCommodityCosts(null == multiple ? null : multiple.getCommodityCosts());
//                    }
//                }
//            }
        }
        return commodityList;
    }

    /**
     * 获取到所有的商品成本属性后，根据属性分组
     *
     * @param multiples 多规格商品集合
     * @return 商品属性集合
     */
    private Map<Long, List<CommodityCostAttributeDTO>> getMultipleCommodityCostAttributeMapByAttributeId(List<CommodityInfoListDTO> multiples) {
        Map<Long, List<CommodityCostAttributeDTO>> result = null;
        List<Long> multipleCommodityIds = multiples.stream().map(p -> p.getId()).collect(Collectors.toList());
        List<CommodityCostAttribute> list = costAttributeMapper.selectByIds(multipleCommodityIds, IsDeletedCode.NO.getCode());
        List<CommodityCostAttributeDTO> costAttributeList = EntityUtil.copyList(list, CommodityCostAttributeDTO.class);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(costAttributeList)) {
            result = costAttributeList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityAttributeId()));
        }
        return result;
    }

    /**
     * 获取到所有的商品成本后，根据商品属性分组
     *
     * @param singles 单规格商品集合
     * @return 商品属性分组后的商品集合
     */
    private Map<Long, List<CommodityCostDTO>> getSingleCommodityCostMapByAttributeId(List<CommodityInfoListDTO> singles) {
        Map<Long, List<CommodityCostDTO>> result = null;
        List<Long> singleCommodityIds = singles.stream().map(p -> p.getId()).collect(Collectors.toList());
        List<CommodityCost> list = costMapper.selectListByIds(singleCommodityIds, IsDeletedCode.NO.getCode());
        List<CommodityCostDTO> resultList = EntityUtil.copyList(
                list, CommodityCostDTO.class);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(resultList)) {
            result = resultList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityAttributeId()));
        }
        return result;
    }

    /**
     * 上架商品信息到es
     *
     * @return
     */
    private void upClassificationEs(List<CommodityInfoListDTO> commodityAllList) {
        elasticSearchCommodityMapper.deleteAll();
        elasticSearchCommodityMapper.saveAll(commodityAllList);
    }


    @Override
    public Result updateCommodityCacheData() {
        List<CommodityInfoListDTO> commodityAllList = findCommodityAllList(LocalDateTime.now());
        List<CommodityInfoListDTO> commodityAllList2 = new ArrayList<>();

        // 查询商品七天内的销售数据
        List<com.ctshk.rpc.goods.dto.resp.CountVo> salesMap = commodityService.findSavenDaysCommodityNumber();
        if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(commodityAllList)) {
            log.info("【查询商品数据封装，数据返参为:{}】", JSON.toJSONString(commodityAllList));
            for (CommodityInfoListDTO commodityInfoListDTO : commodityAllList) {
                if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(salesMap)) {
                    log.info("【查询商品七天内的销售数据，数据返参为:{}】", JSON.toJSONString(salesMap));
                    for (com.ctshk.rpc.goods.dto.resp.CountVo stringStringMap : salesMap) {
                        if (commodityInfoListDTO.getId().longValue() == Long.parseLong(stringStringMap.getCommodityId())) {
                            commodityInfoListDTO.setSales(Long.parseLong(stringStringMap.getCount()));
                        } else {
                            commodityInfoListDTO.setSales(0L);
                        }
                    }
                } else {
                    commodityInfoListDTO.setSales(0L);
                }
                commodityAllList2.add(commodityInfoListDTO);
            }
            upClassificationEs(commodityAllList2);
        }
        return Result.success();
    }

    /**
     * 构建PC 检索结果
     *
     * @param response
     * @return
     */
    public List<CommodityInfoResp> buildCommodityInfoResp(SearchResponse response) {
        List<CommodityInfoResp> commodityInfoResps = new ArrayList<>();

        // 检索到的命中记录
        SearchHits hits = response.getHits();

        // 提取检索到的记录
        SearchHit[] searchHits = hits.getHits();
        if (searchHits != null && searchHits.length > 0) {
            for (SearchHit hit : searchHits) {
                CommodityInfoResp commodityInfoResp = new CommodityInfoResp();
                String source = hit.getSourceAsString();
                // 将命中记录反序列化成行程对象和目的地对象
                CommodityInfoListDTO commodityInfoListDTO = JSON.parseObject(source, CommodityInfoListDTO.class);
                log.info("【命中结果为：{}】", JSON.toJSONString(commodityInfoListDTO));
                commodityInfoResp.setCommodityName(commodityInfoListDTO.getCommodityName());
                // 单规格
                List<CommodityCostResp> commodityCosts = new ArrayList<>();
                if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(commodityInfoListDTO.getCommodityCosts())) {
                    for (CommodityCostDTO commodityCost : commodityInfoListDTO.getCommodityCosts()) {
                        CommodityCostResp cost = new CommodityCostResp();
                        cost.setCostPrice(commodityCost.getCostPrice());
                        cost.setMarkingPrice(commodityCost.getMarkingPrice());
                        cost.setPictureUrl(commodityCost.getPictureUrl());
                        commodityCosts.add(cost);
                    }
                }
                // 多规格
                List<CommodityCostAttributeResp> commodityCostAttributeResps = new ArrayList<>();
                if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(commodityInfoListDTO.getCommodityCostAttributes())) {
                    for (CommodityCostAttributeDTO commodityCostAttribute : commodityInfoListDTO.getCommodityCostAttributes()) {
                        CommodityCostResp cost = new CommodityCostResp();
                        cost.setCostPrice(commodityCostAttribute.getCommodityCost().getCostPrice());
                        cost.setMarkingPrice(commodityCostAttribute.getCommodityCost().getMarkingPrice());
                        cost.setPictureUrl(commodityCostAttribute.getCommodityCost().getPictureUrl());
                        commodityCosts.add(cost);
//                        CommodityCostAttributeResp commodityCostAttributeResp = new CommodityCostAttributeResp();
//                        commodityCostAttributeResp.setCostPrice(commodityCostAttribute.getCommodityCost().getCostPrice());
//                        commodityCostAttributeResp.setMarkingPrice(commodityCostAttribute.getCommodityCost().getMarkingPrice());
//                        commodityCostAttributeResp.setPictureUrl(commodityCostAttribute.getCommodityCost().getPictureUrl());
//                        commodityCostAttributeResps.add(commodityCostAttributeResp);
                    }
                }
                // 商品属性
                if (null != commodityInfoListDTO.getCommodityAttribute()) {
                    commodityInfoResp.setCommodityAttribute(commodityInfoListDTO.getCommodityAttribute());
                }
                // 商品标签
                if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(commodityInfoListDTO.getCommodityLabels())) {
                    for (CommodityLabelDTO commodityLabel : commodityInfoListDTO.getCommodityLabels()) {
                        commodityInfoResp.setLabelType(commodityLabel.getLabelType());
                    }
                }
                List<CommodityFileDTO> commodityFileList = new ArrayList<>();
                if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(commodityInfoListDTO.getCommodityFiles())) {
                    for (CommodityFileDTO commodityFile : commodityInfoListDTO.getCommodityFiles()) {
                        if (commodityFile.getFileType().intValue() == 2) {
                            CommodityFileDTO commodityFileDTO = new CommodityFileDTO();
                            Long commodityId = commodityFile.getCommodityId();
                            Long id = commodityFile.getId();
                            String fileName = commodityFile.getFileName();
                            String fileUrl = commodityFile.getFileUrl();
                            Integer fileType = commodityFile.getFileType();
                            Integer isDeleted = commodityFile.getIsDeleted();
                            commodityFileDTO.setCommodityId(commodityId);
                            commodityFileDTO.setFileName(fileName);
                            commodityFileDTO.setFileType(fileType);
                            commodityFileDTO.setFileUrl(fileUrl);
                            commodityFileDTO.setIsDeleted(isDeleted);
                            commodityFileDTO.setId(id);
                            commodityFileList.add(commodityFileDTO);
                        }
                    }
                    commodityInfoResp.setCommodityFileList(commodityFileList);
                }
                Long sales = commodityInfoListDTO.getSales();
                if (null != sales) {
                    commodityInfoResp.setSales(sales.toString());
                }
                commodityInfoResp.setId(commodityInfoListDTO.getId());
                commodityInfoResp.setCommodityClassificationId(commodityInfoListDTO.getCommodityClassificationId());
                String commodityClassificationName = commodityInfoListDTO.getCommodityClassificationName();
                commodityInfoResp.setCommodityClassificationName(commodityClassificationName);
                commodityInfoResp.setCommodityCostAttributes(commodityCostAttributeResps);
                commodityInfoResp.setCommodityCost(commodityCosts);
                commodityInfoResp.setCommodityName(commodityInfoListDTO.getCommodityName());
                commodityInfoResps.add(commodityInfoResp);
            }
        }
        return commodityInfoResps;
    }

    @Override
    public Result updateShoppingSpecial() {
        try {
            List<ShoppingSpecial> shoppingSpecials = shoppingSpecialMapper.selectAllList();
            List<ShoppingSpecialDetailedDTO> specialPageDTOS = new ArrayList<>();
            List<Long> ids = new ArrayList<>();
            if (!CollectionUtils.isEmpty(shoppingSpecials)) {
                log.info("【查询商品专题列表，数据返参为:{}】", JSON.toJSONString(shoppingSpecials));
                // 获取专题信息
                for (ShoppingSpecial special : shoppingSpecials) {
                    ShoppingSpecialDetailedDTO specialDetailedDTO = EntityUtil.copy(special, ShoppingSpecialDetailedDTO.class);
                    List<ShoppingSpecialCommodityDetailedDTO> shoppingSpecialCommodityDetailedDTOS = new ArrayList<>();
                    // 查询专题商品信息
                    //                QueryWrapper<ShoppingSpecialCommodity> shoppingSpecialCommodityQueryWrapper = new QueryWrapper<>();
                    //                shoppingSpecialCommodityQueryWrapper.eq("special_id", special.getId());
                    List<ShoppingSpecialCommodity> shoppingSpecialCommodities = shoppingSpecialCommodityMapper.selectAllList(special.getId());
                    if (!CollectionUtils.isEmpty(shoppingSpecialCommodities)) {
                        // 获取商品详细信息
                        for (ShoppingSpecialCommodity specialCommodity : shoppingSpecialCommodities) {
                            ids.add(specialCommodity.getCommodityId());
                        }
                        List<CommodityInfoResp> commodityInfoResps = new ArrayList<>();
                        // 构建DSL语句
                        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                        QueryBuilder queryBuilder = QueryBuilders.termsQuery("id", ids);
                        sourceBuilder.query(queryBuilder);
                        SearchRequest searchRequest = new SearchRequest(ElasticSearchConstant.GOODS_INDEX).source(sourceBuilder);
                        try {
                            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, ElasticSearchConfiguration.COMMON_OPTIONS);
                            commodityInfoResps = buildCommodityInfoResp(searchResponse);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        for (CommodityInfoResp commodityInfoResp : commodityInfoResps) {
                            ShoppingSpecialCommodityDetailedDTO specialCommodityDetailedDTO = EntityUtil.copy(commodityInfoResp, ShoppingSpecialCommodityDetailedDTO.class);
                            if (org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty(commodityInfoResp.getCommodityCost())) {
                                specialCommodityDetailedDTO.setPrice(commodityInfoResp.getCommodityCost().get(0).getCostPrice());
                                specialCommodityDetailedDTO.setMarkingPrice(commodityInfoResp.getCommodityCost().get(0).getMarkingPrice());
                            }
                            specialCommodityDetailedDTO.setLabelType(commodityInfoResp.getLabelType());
                            shoppingSpecialCommodityDetailedDTOS.add(specialCommodityDetailedDTO);
                        }
                        specialDetailedDTO.setCommodityDetailedList(shoppingSpecialCommodityDetailedDTOS);
                    }
                    specialPageDTOS.add(specialDetailedDTO);
                }
                redisTemplate.delete(RedisConstants.GOODS_HOME_SPECIAL);
                // 上架Redis
                redisTemplate.opsForValue().set(RedisConstants.GOODS_HOME_SPECIAL, JSON.toJSONString(specialPageDTOS));
            } else {
                for (ShoppingSpecial special : shoppingSpecials) {
                    ShoppingSpecialPageDTO pageDTO = EntityUtil.copy(special, ShoppingSpecialPageDTO.class);
                    //                specialPageDTOS.add(pageDTO);
                }
                redisTemplate.delete(RedisConstants.GOODS_HOME_SPECIAL);
                // 上架Redis
                redisTemplate.opsForValue().set(RedisConstants.GOODS_HOME_SPECIAL, JSON.toJSONString(specialPageDTOS));
            }
        } catch (Exception e) {
            log.error("【更新商品专题失败，错误为：{}】",e.getMessage());
            e.printStackTrace();
        }
        return Result.success();
}

    public void setMultiSpecificationRelatedParamInfo(CommodityDTO commodityDTO, CommodityAttributeReq attributeReq) {
        List<CommodityCostSingleReq> dbCommodityCostSingleList = costMapper.findCommodityCostAndAttributeByCombinedIds(commodityDTO.getId(), attributeReq.getId());
        if (dbCommodityCostSingleList != null) {
            commodityDTO.setCommodityCostReqList(dbCommodityCostSingleList);
            List<Long> specificationsAttributeId = new ArrayList<>();
            for (CommodityCostSingleReq costSingleReq : dbCommodityCostSingleList) {
                CommodityCostAttributeReq costAttributeReq = costSingleReq.getCommodityCostAttributeReq();
                if (!specificationsAttributeId.contains(costAttributeReq.getSpecificationsAttributeOneId())) {
                    specificationsAttributeId.add(costAttributeReq.getSpecificationsAttributeOneId());
                }
                if (!specificationsAttributeId.contains(costAttributeReq.getSpecificationsAttributeTwoId())) {
                    specificationsAttributeId.add(costAttributeReq.getSpecificationsAttributeTwoId());
                }
            }
            List<ShoppingCommoditySpecificationsAttribute> specificationsAttributeList = specificationsAttributeMapper.selectBatchIds(specificationsAttributeId);

            Long specificationsNameId = null;
            List<Long> specificationsId = new ArrayList<>();
            if (null != specificationsAttributeList && specificationsAttributeList.size() > 0) {
                specificationsNameId = specificationsAttributeList.get(0).getSpecificationsNameId();
                for (ShoppingCommoditySpecificationsAttribute specificationsAttribute : specificationsAttributeList) {
                    if (!specificationsId.contains(specificationsAttribute.getSpecificationsId())) {
                        specificationsId.add(specificationsAttribute.getSpecificationsId());
                    }
                }

                // =========== 多规格类型中，用到了商品规格模板参数，所以这里需要取规格模板数据去做一个比对操作 Start===========
                ShoppingCommoditySpecificationsName specificationsName = specificationsNameMapper.selectById(specificationsNameId);
                ShoppingCommoditySpecificationsNameReq specificationsNameReq = new ShoppingCommoditySpecificationsNameReq();
                BeanUtils.copyProperties(specificationsName, specificationsNameReq);

                List<ShoppingCommoditySpecifications> dbShoppingCommoditySpecificationsList = specificationsMapper.findSpecificationsByNameId(specificationsNameId);
                List<ShoppingCommoditySpecificationsReq> specificationsReqs = new ArrayList<>();

                // 通过指定的规格名称下的规格二级菜单，去比对本次操作的具体属性
                for (ShoppingCommoditySpecifications dbSpecifications : dbShoppingCommoditySpecificationsList) {
                    ShoppingCommoditySpecificationsReq specificationsReq = new ShoppingCommoditySpecificationsReq();
                    BeanUtils.copyProperties(dbSpecifications, specificationsReq);
                    List<ShoppingCommoditySpecificationsAttributeReq> specificationsAttributeReqs = new ArrayList<>();
                    for (ShoppingCommoditySpecificationsAttribute specificationsAttribute : specificationsAttributeList) {
                        if (specificationsNameId.longValue() == specificationsAttribute.getSpecificationsNameId().longValue()
                                && (specificationsReq.getId().longValue() == specificationsAttribute.getSpecificationsId().longValue())) {
                            ShoppingCommoditySpecificationsAttributeReq specificationsAttributeReq = new ShoppingCommoditySpecificationsAttributeReq();
                            BeanUtils.copyProperties(specificationsAttribute, specificationsAttributeReq);
                            specificationsAttributeReqs.add(specificationsAttributeReq);
                        }
                    }
                    specificationsReq.setShoppingCommoditySpecificationsAttributeReqList(specificationsAttributeReqs);
                    specificationsReqs.add(specificationsReq);
                }
                specificationsNameReq.setShoppingCommoditySpecificationsReqList(specificationsReqs);
                // =========== 多规格类型中，用到了商品规格模板参数，所以这里需要取规格模板数据去做一个比对操作 End===========

                commodityDTO.setShoppingCommoditySpecificationsNameReq(specificationsNameReq);
            }
        }
    }
}